import { loadFbxModel } from "./loadModel";
import * as THREE from "three"
import { SurroundLine } from "../effect/SurroundLine";
import { Background } from "../effect/Background"
import { Radar } from "../effect/Radar";
import { Wall } from "../effect/Wall";
import { Ball } from "../effect/Ball";
import { Cone } from "../effect/Cone"
import { MyCurve } from "../effect/Curve";
import { Road } from "../effect/Road";
import { Font } from "../effect/Font";
import { Snow } from "../effect/Snow";
import { Rain } from "../effect/Rain";
import * as TWEEN from "@tweenjs/tween.js"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"

export class City {
    scene: THREE.Scene
    camera: THREE.Camera
    renderer: THREE.WebGLRenderer
    // background: Background
    // radar: Radar
    // wall: Wall
    // ball: Ball
    // cone: Cone
    up_height: THREE.IUniform
    move_line: THREE.IUniform
    time: THREE.IUniform
    controls
    effectList: any[]
    constructor(scene: THREE.Scene, camera: THREE.Camera, renderer: THREE.WebGLRenderer, controls: OrbitControls) {
        this.scene = scene
        this.camera = camera
        this.renderer = renderer
        this.controls = controls
        // this.background = {} as Background
        // this.radar = {} as Radar
        // this.wall = {} as Wall
        // this.ball = {} as Ball
        // this.cone = {} as Cone

        this.effectList = []
        this.up_height = {
            value: 5
        }
        this.move_line = {
            value: -3000
        }
        this.time = { value: 0 }


        this.loadFbx()
    }
    loadFbx() {
        loadFbxModel("/src/assets/model/beijing.fbx").then((group) => {
            // this.scene.add(group)
            group.traverse((child) => {
                if ((child as THREE.Mesh).isMesh) {
                    //自定义模型mesh
                    new SurroundLine(this.scene, child as THREE.Mesh, this.up_height, this.move_line)
                }
            })
            this.initEffect()
        })
    }
    initEffect() {
        this.initBackground()
        this.initRadar()
        this.initWall()
        this.initBall()
        this.initCone()
        this.initCurve()
        this.initRoad()
        // this.initFont()
        // this.initSnow()
        // this.initRain()
        this.initClick()
        this.initWheel()
    }
    initBackground() {
        this.effectList.push(
            new Background(this.scene)
        )
    }
    initRadar() {
        this.effectList.push(
            new Radar(this.scene, this.time)
        )
    }
    initWall() {
        this.effectList.push(
            new Wall(this.scene, this.time)
        )
    }
    initBall() {
        this.effectList.push(
            new Ball(this.scene, this.time)
        )
    }
    initCone() {
        this.effectList.push(new Cone(this.scene, this.time)
        )
    }
    initCurve() {
        this.effectList.push(
            new MyCurve(this.scene, this.time)
        )
    }
    initRoad() {
        this.effectList.push(
            new Road(this.scene, this.time)
        )
    }
    initFont() {
        this.effectList.push(
            new Font(this.scene)
        )
    }
    initSnow() {
        this.effectList.push(
            new Snow(this.scene)
        )
    }
    initRain() {
        this.effectList.push(new Rain(this.scene))
    }
    initClick() {
        let flag = true;
        let { renderer } = this

        renderer.domElement.onmousedown = () => {
            flag = true;

            renderer.domElement.onmousemove = () => {
                flag = false;
            }
        }

        renderer.domElement.onmouseup = (event) => {
            if (flag) {
                this.clickEvent(event)
            }
            renderer.domElement.onmousemove = null;
        }


    }
    clickEvent(event: MouseEvent) {
        let { scene, camera } = this
        // 获取到浏览器坐标
        const x = (event.clientX / window.innerWidth) * 2 - 1;
        const y = -(event.clientY / window.innerHeight) * 2 + 1;

        // 创建设备坐标（三维）
        const standardVector = new THREE.Vector2(x, y);

        // 转化为世界坐标
        // const worldVector = standardVector.unproject(camera);

        // 做序列化
        // const ray = worldVector.sub(camera.position).normalize();

        // 如何实现点击选中
        // 创建一个射线发射器，用来发射一条射线
        const raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(standardVector, camera)

        // 返回射线碰撞到的物体
        const intersects = raycaster.intersectObjects(scene.children);
        console.log(intersects);

        let point3d;
        if (intersects.length) {
            point3d = intersects[0]
        }
        if (point3d) {
            let time = 2000, a = 3
            // if (point3d.distance > 2500) return
            new TWEEN.Tween(camera.position).to({
                x: point3d.point.x * a,
                y: point3d.point.y * a,
                z: point3d.point.z * a
            }, time).start()

            new TWEEN.Tween(camera.rotation).to({
                x: camera.rotation.x,
                y: camera.rotation.y,
                z: camera.rotation.z
            }, time).start()
        }
    }
    initWheel() {
        let { renderer, camera } = this
        const body = document.body
        body.addEventListener('mousewheel', (e) => {
            let event = e as WheelEvent
            const value = 30;

            // 鼠标当前的坐标信息
            const x = (event.clientX / window.innerWidth) * 2 - 1;
            const y = -(event.clientY / window.innerHeight) * 2 + 1;

            const vector = new THREE.Vector3(x, y, 0.5);
            vector.unproject(this.camera)
            vector.sub(this.camera.position).normalize()
            if (event.wheelDelta > 0) {
                this.camera.position.x += vector.x * value;
                this.camera.position.y += vector.y * value;
                this.camera.position.z += vector.z * value;

                this.controls.target.x += vector.x * value;
                this.controls.target.y += vector.y * value;
                this.controls.target.z += vector.z * value;
            } else {
                this.camera.position.x -= vector.x * value;
                this.camera.position.y -= vector.y * value;
                this.camera.position.z -= vector.z * value;

                this.controls.target.x -= vector.x * value;
                this.controls.target.y -= vector.y * value;
                this.controls.target.z -= vector.z * value;
            }

        })
    }
    start(delta: number) {
        // this.three.camera.rotation.z+=0.01
        // if (this.tweenPosition && this.tweenRotation) {
        //     this.tweenPosition.update()
        //     this.tweenRotation.update()
        // }
        this.time.value += delta
        // console.log(this.time);
        this.effectList.forEach(effect => {
            effect.animation && effect.animation()
        })

        TWEEN.update()
        this.up_height.value += 0.3
        if (this.up_height.value > 200) {
            this.up_height.value = 5
        }
        this.move_line.value += 3
        if (this.move_line.value > 2000) {
            this.move_line.value = -3000
        }
    }
}